package com.lft.queue01;

/**
 * 数组模拟队列
 * 队列特点：先前先出
 */
public class ArrayQueue {
	/**
	 * 表示数组的最大容量。
	 */
	private int maxSize;
	
	/**
	 * 队列头
	 */
	private int front;
	/**
	 * 队列尾
	 */
	private int rear;
	
	/**
	 * 用于存放数据的数组，模拟队列
	 */
	private Object[] arr;
	
	/**
	 * 创建一个明确容量的队列
	 * @param maxSize 队列容量大小
	 */
	public ArrayQueue(int maxSize) {
		this.maxSize = maxSize;
		arr = new Object[maxSize];
		// 指向队列头部。front是指向队列头的前一个位置。
		front = -1;
		// 指向队列尾部。rear是指向队列尾的最后一个数据(即就是队列最后一个数据)。
		rear = -1;
	}
	
	/**
	 * 判断队列是否已满
	 * @return true 满，false 不满
	 */
	public boolean isFull() {
		return rear == maxSize - 1;
	}
	
	/**
	 * 判断队列是否为空
	 * @return true 空，false 非空
	 */
	public boolean isEmpty() {
		return rear == front;
	}
	
	/**
	 * 添加数据到队列(进队列)
	 * @param n 需要添加的数据
	 */
	public void addQueue(Object n) {
		// 判断队列是否已满
		if (isFull()) {
			System.out.println("队列满了，不能添加数据~~");
			return;
		}
		// 让rear后移一位
		rear++;
		// 将数据添加进队列
		arr[rear] = n;
	}
	
	/**
	 * 获取队列中的数据(出队列)。
	 * @return 取出当前队列中的头数据。
	 */
	public Object getQueue() {
		// 判断队列是否为空
		if (isEmpty()) {
			throw new RuntimeException("队列为空，不能取数据");
		}
		front++;
		Object temp = arr[front];
		// 获取完队列中的数据将当前索引下的数组元素置空，防止内存泄漏。
		arr[front] = null;
		return temp;
	}
	
	/**
	 * 显示队列中的所有数据
	 */
	public void showQueue() {
		// 判断队列是否为空
		if (isEmpty()) {
			System.out.println("队列为空，没有数据~~");
			return;
		}
		for (int i = 0; i < arr.length; i++) {
			System.out.printf("arr[%d] = %s\n", i, arr[i]);
		}
	}
	
	/**
	 * 显示队列的头数据，【注意】不是取出数据。
	 * @return 显示头数据
	 */
	public Object headQueue() {
		// 判断队列是否为空
		if (isEmpty()) {
			throw new RuntimeException("队列为空，没有数据");
		}
		return arr[front + 1];
	}
}
